﻿using System;
using System.Runtime.CompilerServices;
using eNets.CBK.Pipe;
using eNets.CBK.Sockets;

namespace eNets.CBK.Session.Tcp;

partial class TcpSession
{
    private IPipe<byte> sndPipe;
    private TcpSocketSndOper sndOper;
    private SequencePosition sequenceSndPos;

    private IPipeReader<byte> SndPipeReader
    {
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        get { return this.sndPipe.Reader; }
    }

    public void SndStartAsync()
    {
        this.SndPipeReader.AddListener(this.OnRcvPipeSequence);
        this.SndPipeReader.RcvAsync();
    }

    private void OnRcvPipeSequence()
    {
        var sequence = SndPipeReader.GetReadableSequence();
        
        this.sequenceSndPos = sequence.End;
        this.sndOper.SendAsync(sequence);
    }
    
    private void OnSocketSndCompleted(in SocketResult result)
    {
        if (!SocketOperationUtil.TryCompleted(result, out var error))
        {
            return;
        }

        if (result.Count == 0)
        {
            return;
        }

        this.SndPipeReader.ReaderAdvanceTo(sequenceSndPos);
        this.SndPipeReader.Flush();
        this.SndPipeReader.RcvAsync();
    }
}